/******************************************************************************\
 *
 * File Name   : oslite.h
 *
 * Description : os envelop for fast eviroment migration
 *
 *
\******************************************************************************/

#ifndef __OSLITE_H
#define __OSLITE_H
#include <assert.h>

#if defined(TI_BIOS)
#include <std.h>
#include <log.h>
#include <sem.h>
#include <sys.h>
#include <tsk.h>
#include <msgq.h>
#include <pool.h>
#include <staticpool.h>
#endif


#if defined(LINUX)
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
#include <string.h>
#include <memory.h>
#include <stdarg.h>
#include <assert.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <semaphore.h>


#endif

#if defined (WIN32)
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#define DLLEXPORT_API __declspec(dllexport)
#define DLLIMPORT_API __declspec(dllimport)
#endif


#ifdef __cplusplus
extern "C" {
#endif
#include "commontypes.h"

#define PRINT_ERROR
#define PRINT_DEBUG

//#define DEBUG



typedef unsigned long partition_t;


typedef struct
{
  short                    partition_status_state;
  short                    partition_status_type;
  int                      partition_status_size;
  int                      partition_status_free;
  int                      partition_status_free_largest;
  int                      partition_status_used;
  int                      partition_status_unused[4];
} OS_PartitionStatus_t;


typedef struct{
int    sec ;  /*seconds [0,61] */
int    min;   /*minutes [0,59]*/
int    hour;  /*hour [0,23]*/
int    mday;  /*day of month [1,31]*/
int    mon ; /*month of year [0,11]*/
int    year; /* years since 1900*/
}OS_SystemTime_t;

typedef enum{
	SHARED_MEM_PARTITION,
	CACHED_PARTITION,
	NCACHED_PARTITION,
	FAST_ACCESS_PARTITION,
	INTERNAL_MEM_PARTITION
}PartitionID_t;


/* General purpose string type -------------------------------------------- */
typedef char*          OS_String_t   ;

/* Function return error code --------------------------------------------- */
typedef U32            OS_ErrorCode_t;

/* Revision structure ----------------------------------------------------- */
typedef const char *   OS_Revision_t ;

/* Generic handle type ---------------------------------------------------- */
typedef U32            OS_Handle_t   ;

/* Generic partition type ------------------------------------------------- */
typedef partition_t    OS_Partition_t;

typedef U32  OS_Fifo_t;
/* Generic terminate parameters ------------------------------------------- */
typedef struct
{
    BOOL ForceTerminate;
} OS_TermParams_t;


#if defined (LINUX)

typedef pthread_mutex_t OS_mutex_t;
#define STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER
typedef pthread_cond_t  OS_cond_t;
typedef pthread_key_t   OS_threadvar_t;

#elif defined( WIN32 )
typedef struct
{
    LONG initialized;
    CRITICAL_SECTION mutex;
} OS_mutex_t;

#define VLC_STATIC_MUTEX { 0, }


typedef HANDLE  OS_cond_t;
typedef DWORD   OS_threadvar_t;

#endif





/* Device name type ------------------------------------------------------- */
#define OS_MAX_DEVICE_NAME 16  /* 15 characters plus '\0' */
typedef char OS_DeviceName_t[OS_MAX_DEVICE_NAME];

/* Exported Constants ----------------------------------------------------- */

/* BOOL type constant values ---------------------------------------------- */
#ifndef TRUE
    #define TRUE (1 == 1)
#endif
#ifndef FALSE
    #define FALSE (!TRUE)
#endif

/* Common driver error constants ------------------------------------------ */
#define OS_DRIVER_ID    0
#define OS_DRIVER_BASE (OS_DRIVER_ID << 16)
enum
{
    OS_NO_ERROR = OS_DRIVER_BASE,
    OS_ERROR_BAD_PARAMETER,             /* Bad parameter passed       */
    OS_ERROR_NO_MEMORY,                 /* Memory allocation failed   */
    OS_ERROR_UNKNOWN_DEVICE,            /* Unknown device name        */
    OS_ERROR_ALREADY_INITIALIZED,       /* Device already initialized */
    OS_ERROR_NO_FREE_HANDLES,           /* Cannot open device again   */
    OS_ERROR_OPEN_HANDLE,               /* At least one open handle   */
    OS_ERROR_INVALID_HANDLE,            /* Handle is not valid        */
    OS_ERROR_FEATURE_NOT_SUPPORTED,     /* Feature unavailable        */
    OS_ERROR_REVISION_NOT_SUPPORTED,    /* Revision not available     */
    OS_ERROR_INTERRUPT_INSTALL,         /* Interrupt install failed   */
    OS_ERROR_INTERRUPT_UNINSTALL,       /* Interrupt uninstall failed */
    OS_ERROR_TIMEOUT,                   /* Timeout occured            */
    OS_ERROR_DEVICE_BUSY ,               /* Device is currently busy  */
	OS_ERROR_MUTEX_FAIL                   /* MUTEX Failue               */
};





typedef enum DEBUG_ReportLevel_e
{                                   /* Use the given level to indicate: */
    DEBUG_REPORT_LEVEL_FATAL = 0,   /* Imminent non recoverable system failure */
    DEBUG_REPORT_LEVEL_ERROR,       /* Serious error, though recoverable */
    DEBUG_REPORT_LEVEL_WARNING,     /* Warnings of unusual occurences */
    DEBUG_REPORT_LEVEL_ENTER_LEAVE_FN, /* Entrance or exit of a function, and parameter display */
    DEBUG_REPORT_LEVEL_INFO,        /* Status and other information - normal though */
    DEBUG_REPORT_LEVEL_USER1,       /* User specific */
    DEBUG_REPORT_LEVEL_USER2,       /* User specific */

    /* Keep as last one (Internal use only) */
    DEBUG_NB_OF_REPORT_LEVEL        /* Last element has a value corresponding to the number of elements by default ! */
} DEBUG_ReportLevel_t;

/* Defines the various types of outputs that can be filtered */
typedef enum DEBUG_OutputType_e
{
    DEBUG_OUTPUT_ALL,           /* All outputs together */
    DEBUG_OUTPUT_PRINT,         /* Only DEBUG_Print */
    DEBUG_OUTPUT_REPORT,        /* Only DEBUG_Report (all report levels) */
    DEBUG_OUTPUT_REPORT_FATAL,  /* Only DEBUG_Report with report level fatal */
    DEBUG_OUTPUT_REPORT_ERROR,  /* Only DEBUG_Report with report level error */
    DEBUG_OUTPUT_REPORT_WARNING, /* Only DEBUG_Report with report level warning */
    DEBUG_OUTPUT_REPORT_ENTER_LEAVE_FN, /* Only DEBUG_Report with report level enter/leave function */
    DEBUG_OUTPUT_REPORT_INFO,   /* Only DEBUG_Report with report level info */
    DEBUG_OUTPUT_REPORT_USER1,  /* Only DEBUG_Report with report level user1 */
    DEBUG_OUTPUT_REPORT_USER2,  /* Only DEBUG_Report with report level user2 */

    /* Keep as last one (Internal use only) */
    DEBUG_NB_OF_OUTPUTS         /* Last element has a value corresponding to the number of elements by default ! */
} DEBUG_OutputType_t;


#define THREAD_PRIORITY_LOW      0
#define THREAD_PRIORITY_MEDUM    5
#define THREAD_PRIORITY_HIGH     10


#define THREAD_PRIORITY_INPUT   10
#define THREAD_PRIORITY_AUDIO    5
#define THREAD_PRIORITY_VIDEO    0
#define THREAD_PRIORITY_OUTPUT  15
#define THREAD_PRIORITY_HIGHEST 20




#if defined(WIN32)
typedef unsigned long OS_Task_t;
typedef unsigned long OS_Semaphore_t;
#elif defined(TI_BIOS)
typedef TSK_Handle OS_Task_t;
typedef SEM_Handle OS_Semaphore_t;
#elif defined(LINUX)
 typedef pthread_t OS_Task_t;
 typedef unsigned long OS_Semaphore_t;
#endif



#if defined(FREESCALE_NETCOMM)
typedef unsigned long OS_Task_t;
typedef unsigned long OS_Semaphore_t;
#endif


typedef void * (*OS_TaskFunc_t)(void *);
typedef void (*ISRHandler_t)(void *);


void DebugPrint(char *fmt,...);
void DebugBlock(void);
void DebugRelease(void);
void my_assert(int);


#if defined(TI_BIOS)
extern LOG_Obj logTrace;
#define LOG  LOG_printf
#else
extern U32 logTrace;
#define LOG
#endif


#if defined(PRINT_DEBUG)
#define PRINTDBG(_x_)	{DebugBlock(); DebugPrint("(%d) %s %d ",OS_GetKHClock(), __FILE__, __LINE__); DebugPrint _x_; DebugRelease();}
#else
#define PRINTDBG(_x_)
#endif


#if defined(DEBUG_REPORT)
    #define DEBUG_Report(_x_){DebugBlock();DebugPrint("%s,%d ", __FILE__, __LINE__);DebugReport _x_;DebugRelease ();}
#else /* not STTBX_REPORT */
    #define DEBUG_Report(_x_)
#endif

#ifndef	dbg_assert
#ifdef DEBUG
#define dbg_assert(e) assert((e))
#else
#define dbg_assert(e)
#endif
#endif


#define TIMEOUT_INFINITY  (U32)-1
#define TIMEOUT_IMMEDIATE  (U32)0

#define OS_TIMEOUT -1
#define OS_SUCCESS 0

// DSP One One shot Task

/**********************************************
				task
************************************************/
OS_Task_t  OS_TaskCreate(U32 StackSize,char *TaskName, OS_TaskFunc_t ,int Priority,void *Param);
int OS_TaskWait(OS_Task_t Task,U32 TimeOut);
void OS_TaskDelete(OS_Task_t Task);
OS_Task_t  OS_TaskGetSelf(void);
int OS_IsTaskRunning(OS_Task_t Task);
int  OS_IsTaskEqual(OS_Task_t taskid1,OS_Task_t taskid2);

/**********************************************
				semaphore and signals
************************************************/
int OS_SetSignal(OS_Semaphore_t Semaphore);
int OS_WaitSignal(OS_Semaphore_t Semaphore,OS_Semaphore_t Sig,U32 Time);

int OS_WaitSemaphore(OS_Semaphore_t Semaphore);
int OS_SetSemaphore(OS_Semaphore_t Semaphore);
OS_Semaphore_t OS_AllocSemaphore(void);
int OS_DeleteSemaphore(OS_Semaphore_t Semaphore);
OS_Semaphore_t OS_AllocSignal(void);
int OS_DeleteSignal(OS_Semaphore_t Semaphore);
int OS_SetTaskPriority (OS_Task_t Task,int Priority);
int OS_PartitionStatus(OS_Partition_t Partition, OS_PartitionStatus_t* Status);
int OS_GetSignalCount(OS_Semaphore_t Semaphore);


/**********************************************
				memory alloc
************************************************/
void *OS_MemoryAllocateAlliment(OS_Partition_t partition,int Size,int Alignment,void **Base);
void *OS_MemoryAllocate(OS_Partition_t partition,int size);
void *OS_MemoryReallocate(OS_Partition_t partition,void* block,int size);
void  OS_MemoryFree(OS_Partition_t partition,void* block);
void *OS_MemAlloc(int size);
void OS_MemFree(void *pMem);
OS_Partition_t   OS_GetPartition(PartitionID_t ID);

/**********************************************
				memory fill
************************************************/

void OS_FastCopy(void *dst,void *src,U32 Size);
void OS_FastFill(void *Dest,U8 Value,U32 Size);

/**********************************************
				Interrupt handling
************************************************/

int OS_InterruptInstall(int InterruptNumber,int InterruptLevel,ISRHandler_t ISR,void*pParam);
int OS_InterruptEnable(int InterruptNumber,int Enable);
// For Debug
void OS_InterruptShoot(int InterruptNumber);
void OS_InterruptSetMask(int InterruptNumber,U32 Mask);
U32 OS_InterruptGetEventFlag(int InterruptNumber);
void OS_InterruptSetEvent(int InterruptNumber , U32 Event);
void OS_InterruptClear(int InterruptNumber,U32 Mask);
// Milisecond sleep
void OS_MSleep(U32 ms);
// Micro second sleep
void OS_USleep(U64 ns);
U32 OS_GetKHClock(void);
int64_t OS_GetMHClock(void);
uint64_t OS_NTPtime64 (void);
U32 OS_GetChipID(void);
/**********************************************
					System Time
************************************************/
int OS_GetSystemTime(unsigned int *SystemTime);
int OS_SetSystemTime(unsigned int SystemTime);

/**********************************************
				Communication
************************************************/
int       OS_FifoInit(int NumOfFifo);
void      OS_FifoTerm(void);
OS_Fifo_t OS_FifoCreate(char *key,int FifoSize);
void	  OS_FifoDelete(OS_Fifo_t hFifo);
OS_Fifo_t OS_FifoConnect(char *key);
int       OS_FifoGet(OS_Fifo_t hfifo,void **msg);
int       OS_FifoPut(OS_Fifo_t hfifo,void *msg);
int 	  OS_IsFifoFull(OS_Fifo_t hfifo);


OS_Handle_t  OS_CreateProcess(char *cmdpath,char *arglist[]);
int OS_GetProcessState(OS_Handle_t pid);
int OS_WaitForProcess(OS_Handle_t pid);
int  OS_System(char *commandline);

//****************** NEW **********************/
int OS_mutex_init( OS_mutex_t *p_mutex );
void OS_mutex_unlock (OS_mutex_t *p_mutex);
void OS_mutex_lock (OS_mutex_t *p_mutex);
int OS_mutex_trylock (OS_mutex_t *p_mutex);
void OS_mutex_destroy (OS_mutex_t *p_mutex);
int OS_cond_init( OS_cond_t *p_condvar );
void OS_cond_wait (OS_cond_t *p_condvar, OS_mutex_t *p_mutex);
void OS_cond_broadcast (OS_cond_t *p_condvar);
void OS_cond_signal (OS_cond_t *p_condvar);
void OS_cond_destroy (OS_cond_t *p_condvar);

#if defined (LINUX)
/**
 * Registers a new procedure to run if the thread is cancelled (or otherwise
 * exits prematurely). Any call to vlc_cleanup_push() <b>must</b> paired with a
 * call to either vlc_cleanup_pop() or vlc_cleanup_run(). Branching into or out
 * of the block between these two function calls is not allowed (read: it will
 * likely crash the whole process). If multiple procedures are registered,
 * they are handled in last-in first-out order.
 *
 * @param routine procedure to call if the thread ends
 * @param arg argument for the procedure
 */
#define OS_cleanup_push( routine, arg ) pthread_cleanup_push (routine, arg)

/**
 * Removes a cleanup procedure that was previously registered with
 * vlc_cleanup_push().
 */
#define OS_cleanup_pop( ) pthread_cleanup_pop (0)

/**
 * Removes a cleanup procedure that was previously registered with
 * vlc_cleanup_push(), and executes it.
 */
#define OS_cleanup_run( ) pthread_cleanup_pop (1)


static inline void OS_cleanup_lock (void *lock)
{
    OS_mutex_unlock ((OS_mutex_t *)lock);
}

#define mutex_cleanup_push( lock ) OS_cleanup_push (OS_cleanup_lock, lock)



#endif


#ifdef __cplusplus
}
#endif

#endif
